package com.zzy.demo.common.util.encode;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;


/**
 * 
 * @author guokaige
 *
 */
public class AesEncryptUtil {
	
    static {
        // add BC provider
        Security.addProvider(new BouncyCastleProvider());
    }
	
	
	public static void main(String[] args){
		String key = "0102030405060708";
		String iv="0102030405060708";
		
		String content = "test12321郭";
		System.out.println("加密前：" + content);
		
		// 加密
		String encryptResult = encrypt(content, key,iv);
		System.out.println("加密后：" + encryptResult);
		// 解密
		String decryptResult = decrypt(encryptResult, key,iv);
		System.out.println("解密后：" + decryptResult);

		String content2 = "6BC5750B2BCC8A8F99A3FA03E01E9AD4";
		// 解密
		String decryptStr = decrypt(content2,key,iv);
		System.out.println("解密后：" + decryptStr);
		
	}

	
    /**
     * Description 根据键值进行加密
     * @param data 
     * @param key  加密键byte数组
     * @return
     * @throws Exception
     */
	public static String encrypt(String data, String key,String iv){
        byte[] bt = encryptByte(data, key,iv);
        String strs = Hex.encodeHexString(bt);
        return strs;
    }
 
    /**
     * Description 根据键值进行解密
     * @param data
     * @param key  加密键byte数组
     * @return
     * @throws UnsupportedEncodingException 
     * @throws IOException
     * @throws Exception
     */
	public static String decrypt(String data, String key,String iv){
        byte[] buf = null;
		try {
			buf = Hex.decodeHex(data.toCharArray());
		} catch (DecoderException e) {
			e.printStackTrace();
		}
        byte[] bt = decryptByte(buf,key,iv);
		return new String(bt,Charset.forName("utf-8"));
    }
	
	
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * 加密
	 * 
	 * @param content
	 *            需要加密的内容
	 * @param password
	 *            加密密码
	 * @return
	 */
	public static byte[] encryptByte(String content, String password ,String iv) {
		try {
			//key
			SecretKeySpec key = new SecretKeySpec(password.getBytes(Charset.forName("utf-8")), "AES");
			
			//iv向量
	        byte[] ivByte = iv.getBytes(Charset.forName("utf-8"));
			// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
	        IvParameterSpec ivParamters = new IvParameterSpec(ivByte);
	        
	        //初始化Cipher   "算法/模式/补码方式"
	        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
	        cipher.init(Cipher.ENCRYPT_MODE, key, ivParamters);
	        
			//内容
	        byte[] byteContent = content.getBytes(Charset.forName("utf-8")); 
			byte[] result = cipher.doFinal(byteContent);
			return result;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param content
	 *            待解密内容
	 * @param password
	 *            解密密钥
	 * @return
	 */
	public static byte[] decryptByte(byte[] content, String password , String iv) {
		try {
			//key
			SecretKeySpec key = new SecretKeySpec(password.getBytes(Charset.forName("utf-8")), "AES");
			
			//iv向量
	        byte[] ivByte = iv.getBytes(Charset.forName("utf-8"));
			// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
	        IvParameterSpec ivParamters = new IvParameterSpec(ivByte);
	        
	        //初始化Cipher  "算法/模式/补码方式"
	        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
	        cipher.init(Cipher.DECRYPT_MODE, key, ivParamters);
			
			byte[] result = cipher.doFinal(content);
			return result;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		}
		return null;
	}

	




}
